import { initPhysics } from '../common/game-physics'
import { initGameScene } from '../common/game-scene'
import { generateTerrain } from '../common/terrain-generator'
import * as achievement from './achievement'
import * as stats from './stats'

export class MarbleGame {
  constructor(options = {}) {
    this.players = options.players || []
    this.currentPlayerIndex = 0
    this.round = 1
    this.maxRounds = options.maxRounds || 10
    this.state = {
      marbles: [],
      terrainType: options.terrainType || 'grassland',
      weather: options.weather || 'sunny'
    }

    // 初始化物理引擎和场景
    this.physics = initPhysics()
    this.scene = initGameScene(options.canvas, {
      terrainType: this.state.terrainType,
      cameraAngle: 30
    })

    // 生成地形
    this.terrain = generateTerrain({
      type: this.state.terrainType,
      size: 2000
    })
    this.physics.setTerrain(this.terrain)

    // 设置洞穴位置
    this.setHolePosition()

    // 初始化弹珠
    this.initMarbles()

    // 绑定事件
    this.bindEvents()
  }

  setHolePosition() {
    // 将洞穴放在场地中央
    const center = this.terrain.getConfig().size / 2
    const holePos = [center, center, this.terrain.getHeightAt(center, center)]
    this.physics.setHole(holePos, 50, 0.5)
  }

  initMarbles() {
    this.state.marbles = []

    // 为每个玩家创建弹珠
    this.players.forEach((player, index) => {
      for (let i = 0; i < player.marbleCount; i++) {
        this.state.marbles.push({
          id: `${player.id}-${i}`,
          owner: player.id,
          position: this.getStartPosition(index),
          velocity: [0, 0, 0],
          radius: 20,
          skin: player.skin || 'default',
          inHole: false,
          lastHitBy: null
        })
      }
    })

    this.physics.setMarbles(this.state.marbles)
    this.scene.updateState(this.state)
  }

  getStartPosition(playerIndex) {
    const size = this.terrain.getConfig().size
    const angle = (playerIndex / this.players.length) * Math.PI * 2
    const distance = size * 0.4

    const x = size / 2 + Math.cos(angle) * distance
    const y = size / 2 + Math.sin(angle) * distance
    const z = this.terrain.getHeightAt(x, y) + 50

    return [x, y, z]
  }

  bindEvents() {
    // 弹珠进洞事件
    this.physics.onMarbleInHole = (marble) => {
      this.handleMarbleInHole(marble)
    }
  }

  handleMarbleInHole(marble) {
    const currentPlayer = this.players[this.currentPlayerIndex]
    const marbleOwner = this.players.find(p => p.id === marble.owner)

    // 计算得分
    const score = this.calculateScore(marble)
    currentPlayer.score += score

    // 转移弹珠所有权
    marble.owner = currentPlayer.id
    marbleOwner.marbleCount--
    currentPlayer.marbleCount++

    // 更新成就系统
    achievement.update('marble_captured', currentPlayer)
    achievement.update('marble_lost', marbleOwner)

    // 更新统计数据
    stats.recordMarbleCapture(currentPlayer.id, score)

    // 检查游戏结束条件
    if (this.checkGameEnd()) {
      this.endGame()
      return
    }

    // 切换到下一个玩家
    this.nextTurn()
  }

  calculateScore(marble) {
    // 根据距离、速度等计算得分
    const speed = Math.sqrt(
      marble.velocity[0] ** 2 + 
      marble.velocity[1] ** 2 + 
      marble.velocity[2] ** 2
    )
    return Math.floor(speed * 10)
  }

  shootMarble(marbleId, direction, power) {
    const marble = this.state.marbles.find(m => m.id === marbleId)
    if (!marble || marble.owner !== this.players[this.currentPlayerIndex].id) {
      return false
    }

    // 设置弹珠初速度
    marble.velocity = [
      direction[0] * power,
      direction[1] * power,
      direction[2] * power
    ]

    return true
  }

  nextTurn() {
    this.currentPlayerIndex = (this.currentPlayerIndex + 1) % this.players.length
    if (this.currentPlayerIndex === 0) {
      this.round++
    }

    // 检查回合限制
    if (this.round > this.maxRounds) {
      this.endGame()
    }
  }

  checkGameEnd() {
    // 检查是否有玩家没有弹珠了
    return this.players.some(p => p.marbleCount <= 0) || 
           this.round > this.maxRounds
  }

  endGame() {
    // 计算最终排名
    const rankedPlayers = [...this.players].sort((a, b) => b.score - a.score)
    
    // 更新成就
    achievement.update('game_completed', rankedPlayers[0])
    if (rankedPlayers[0].score > 100) {
      achievement.update('high_score', rankedPlayers[0])
    }

    // 保存统计数据
    stats.recordGameResult(rankedPlayers)

    // 触发游戏结束事件
    if (this.onGameEnd) {
      this.onGameEnd(rankedPlayers)
    }
  }

  dispose() {
    this.physics.dispose()
    this.scene.dispose()
  }
}
